import { Request, Response, NextFunction } from 'express';
import { logger } from '../utils/logger';
import { ResponseUtils } from '../utils/responseUtils';
import {
  COMMON_ERROR_CODES,
  AUTH_ERROR_CODES,
  VALIDATION_ERROR_CODES,
  DATABASE_ERROR_CODES
} from '../utils/errorCodes';
import { DEFAULT_LANGUAGE } from '../config/languages';
import config from '@/config';

// 自定义错误类
export class AppError extends Error {
  public statusCode: number;
  public errorCode: number;
  public isOperational: boolean;

  constructor(message: string, statusCode: number, errorCode?: number) {
    super(message);
    this.statusCode = statusCode;
    this.errorCode = errorCode || statusCode;
    this.isOperational = true;

    Error.captureStackTrace(this, this.constructor);
  }
}

// 错误处理中间件
export const errorHandler = (
  err: Error | AppError,
  req: Request, // Changed from _req to capture request details
  res: Response,
  _next: NextFunction
): void => {
  logger.error(`Error: ${err.message}`);
  logger.error(`Stack: ${err.stack}`);
  logger.error(`URL: ${req.originalUrl}`);
  logger.error(`Method: ${req.method}`);
  logger.error(`IP: ${req.ip}`);

  // 获取请求的语言
  const language = (req as any).language || DEFAULT_LANGUAGE;

  // Prisma错误处理
  if (err.name === 'PrismaClientKnownRequestError') {
    const prismaError = err as any;
    
    // 处理不同的Prisma错误码
    switch (prismaError.code) {
      case 'P2002': // 唯一约束违反
        ResponseUtils.sendError(res, DATABASE_ERROR_CODES.UNIQUE_CONSTRAINT_VIOLATION, undefined, undefined, undefined, language);
        return;
      case 'P2003': // 外键约束违反
        ResponseUtils.sendError(res, DATABASE_ERROR_CODES.FOREIGN_KEY_CONSTRAINT_VIOLATION, undefined, undefined, undefined, language);
        return;
      case 'P2025': // 记录不存在
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.NOT_FOUND, undefined, undefined, undefined, language);
        return;
      case 'P2021': // 表不存在
        ResponseUtils.sendError(res, DATABASE_ERROR_CODES.QUERY_FAILED, undefined, undefined, undefined, language);
        return;
      case 'P2022': // 列不存在
        ResponseUtils.sendError(res, DATABASE_ERROR_CODES.QUERY_FAILED, undefined, undefined, undefined, language);
        return;
      default:
        ResponseUtils.sendError(res, DATABASE_ERROR_CODES.QUERY_FAILED, undefined, undefined, undefined, language);
        return;
    }
  }

  // Prisma验证错误
  if (err.name === 'PrismaClientValidationError') {
    ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, undefined, undefined, undefined, language);
    return;
  }

  // Prisma连接错误
  if (err.name === 'PrismaClientInitializationError') {
    ResponseUtils.sendError(res, DATABASE_ERROR_CODES.CONNECTION_FAILED, undefined, undefined, undefined, language);
    return;
  }

  // JWT错误
  if (err.name === 'JsonWebTokenError') {
    ResponseUtils.sendError(res, AUTH_ERROR_CODES.TOKEN_INVALID, undefined, undefined, undefined, language);
    return;
  }

  if (err.name === 'TokenExpiredError') {
    ResponseUtils.sendError(res, AUTH_ERROR_CODES.TOKEN_EXPIRED, undefined, undefined, undefined, language);
    return;
  }

  if (err.name === 'NotBeforeError') {
    ResponseUtils.sendError(res, AUTH_ERROR_CODES.TOKEN_INVALID, undefined, undefined, undefined, language);
    return;
  }

  // 验证错误
  if (err.name === 'ValidationError') {
    ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.FIELD_TYPE_ERROR, err.message, undefined, undefined, language);
    return;
  }

  // 重复键错误
  if (err.message.includes('Unique constraint failed') || err.message.includes('Duplicate entry')) {
    ResponseUtils.sendError(res, DATABASE_ERROR_CODES.UNIQUE_CONSTRAINT_VIOLATION, undefined, undefined, undefined, language);
    return;
  }

  // 外键约束错误
  if (err.message.includes('Foreign key constraint failed')) {
    ResponseUtils.sendError(res, DATABASE_ERROR_CODES.FOREIGN_KEY_CONSTRAINT_VIOLATION, undefined, undefined, undefined, language);
    return;
  }

  // 网络错误
  if (err.message.includes('ECONNREFUSED') || err.message.includes('ENOTFOUND')) {
    ResponseUtils.sendError(res, DATABASE_ERROR_CODES.CONNECTION_FAILED, undefined, undefined, undefined, language);
    return;
  }

  // 超时错误
  if (err.message.includes('ETIMEDOUT') || err.message.includes('timeout')) {
    ResponseUtils.sendError(res, DATABASE_ERROR_CODES.CONNECTION_TIMEOUT, undefined, undefined, undefined, language);
    return;
  }

  // 处理自定义AppError
  if (err instanceof AppError) {
    const isDev = config.server.environment === 'development';
    const errorResponse = {
      success: false,
      code: err.errorCode,
      message: err.message,
      timestamp: new Date().toISOString(),
      path: req.originalUrl,
      ...(isDev && { stack: err.stack })
    };
    res.status(err.statusCode).json(errorResponse);
    return;
  }

  // 处理其他未知错误
  const isDev = config.server.environment === 'development';
  const errorResponse = {
    success: false,
    code: 500,
    message: '服务器内部错误',
    timestamp: new Date().toISOString(),
    path: req.originalUrl,
    ...(isDev && { stack: err.stack })
  };
  res.status(500).json(errorResponse);
};

// 404错误处理中间件
export const notFoundHandler = (req: Request, res: Response): void => {
  const language = (req as any).language || DEFAULT_LANGUAGE;
  ResponseUtils.sendError(res, COMMON_ERROR_CODES.NOT_FOUND, undefined, undefined, undefined, language);
};

// 异步错误包装器
export const asyncHandler = (fn: Function) => {
  return (req: Request, res: Response, next: NextFunction) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
}; 